﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using Data.GameData;
using Data.GameData.Interfaces;
using GameFramework;
using GUIFramework.Interfaces;
using WeifenLuo.WinFormsUI.Docking;

// For Test
using Data.GameData.Utils;
using Data.GameData.GameMap;
// For Test

namespace GUIFramework
{
    public partial class MainForm : Form
    {
        protected static MainForm thisForm;
        private static DockPanel mainDockingPanel;

        private IGUIFactory iGuiFactory;

        public MainForm()
        {
            InitializeComponent();

            string filepath = Application.StartupPath + @"\Data\";
            Framework.LoadGameDataFiles(filepath);

            thisForm = this;
            mainDockingPanel = dockPanel;

            #region Test Code
            //StarSystem newStar = new StarSystem();
            //SystemBody newPlanet = new SystemBody(newStar.Id, SystemBodyType.PLANET, SystemBodyEnviroment.TYPE_G, 1, 0, null);
            //newPlanet.MapPosition = new MapIndex(newStar.MapId, 5, 5);
            //SystemBody otherPlanet = newPlanet.Clone() as SystemBody;
            //otherPlanet.MapPosition = new MapIndex(newStar.MapId, 8, 8);

            //FillTestData();
            #endregion
        }

        #region FillTestData
        private void FillTestData()
        {
            StarShip destroyer1 = new StarShip(GameDataStore.GetShipClass("DD"));
            StarShip destroyer2 = new StarShip(GameDataStore.GetShipClass("DD"));

            #region DD1 Systems
            destroyer1.AddSystem(GameDataStore.GetShipSystem("S").Clone() as ShipSystem);
            destroyer1.AddSystem(GameDataStore.GetShipSystem("S").Clone() as ShipSystem);
            destroyer1.AddSystem(GameDataStore.GetShipSystem("S").Clone() as ShipSystem);
            destroyer1.AddSystem(GameDataStore.GetShipSystem("S").Clone() as ShipSystem);
            destroyer1.AddSystem(GameDataStore.GetShipSystem("S").Clone() as ShipSystem);
            destroyer1.AddSystem(GameDataStore.GetShipSystem("S").Clone() as ShipSystem);
            destroyer1.AddSystem(GameDataStore.GetShipSystem("A").Clone() as ShipSystem);
            destroyer1.AddSystem(GameDataStore.GetShipSystem("A").Clone() as ShipSystem);
            destroyer1.AddSystem(GameDataStore.GetShipSystem("A").Clone() as ShipSystem);
            destroyer1.AddSystem(GameDataStore.GetShipSystem("A").Clone() as ShipSystem);
            destroyer1.AddSystem(GameDataStore.GetShipSystem("H").Clone() as ShipSystem);
            destroyer1.AddSystem(GameDataStore.GetShipSystem("Ia").Clone() as ShipSystem);
            destroyer1.AddSystem(GameDataStore.GetShipSystem("Ga").Clone() as WeaponSystem);
            destroyer1.AddSystem(GameDataStore.GetShipSystem("Ga").Clone() as WeaponSystem);
            destroyer1.AddSystem(GameDataStore.GetShipSystem("Ia").Clone() as ShipSystem);
            destroyer1.AddSystem(GameDataStore.GetShipSystem("Qa").Clone() as ShipSystem);
            destroyer1.AddSystem(GameDataStore.GetShipSystem("Ia").Clone() as ShipSystem);
            destroyer1.AddSystem(GameDataStore.GetShipSystem("Ia").Clone() as ShipSystem);
            destroyer1.AddSystem(GameDataStore.GetShipSystem("Ga").Clone() as WeaponSystem);
            destroyer1.AddSystem(GameDataStore.GetShipSystem("Ga").Clone() as WeaponSystem);
            destroyer1.AddSystem(GameDataStore.GetShipSystem("Ia").Clone() as ShipSystem);
            destroyer1.AddSystem(GameDataStore.GetShipSystem("Qa").Clone() as ShipSystem);
            #endregion
            #region DD2 Systems
            destroyer2.AddSystem(GameDataStore.GetShipSystem("S").Clone() as ShipSystem);
            destroyer2.AddSystem(GameDataStore.GetShipSystem("S").Clone() as ShipSystem);
            destroyer2.AddSystem(GameDataStore.GetShipSystem("S").Clone() as ShipSystem);
            destroyer2.AddSystem(GameDataStore.GetShipSystem("S").Clone() as ShipSystem);
            destroyer2.AddSystem(GameDataStore.GetShipSystem("A").Clone() as ShipSystem);
            destroyer2.AddSystem(GameDataStore.GetShipSystem("A").Clone() as ShipSystem);
            destroyer2.AddSystem(GameDataStore.GetShipSystem("A").Clone() as ShipSystem);
            destroyer2.AddSystem(GameDataStore.GetShipSystem("A").Clone() as ShipSystem);
            destroyer2.AddSystem(GameDataStore.GetShipSystem("H").Clone() as ShipSystem);
            destroyer2.AddSystem(GameDataStore.GetShipSystem("Ia").Clone() as ShipSystem);
            destroyer2.AddSystem(GameDataStore.GetShipSystem("Ga").Clone() as WeaponSystem);
            destroyer2.AddSystem(GameDataStore.GetShipSystem("Ga").Clone() as WeaponSystem);
            destroyer2.AddSystem(GameDataStore.GetShipSystem("Ia").Clone() as ShipSystem);
            destroyer2.AddSystem(GameDataStore.GetShipSystem("Qa").Clone() as ShipSystem);
            destroyer2.AddSystem(GameDataStore.GetShipSystem("Ia").Clone() as ShipSystem);
            destroyer2.AddSystem(GameDataStore.GetShipSystem("Ia").Clone() as ShipSystem);
            destroyer2.AddSystem(GameDataStore.GetShipSystem("Ga").Clone() as WeaponSystem);
            destroyer2.AddSystem(GameDataStore.GetShipSystem("Ga").Clone() as WeaponSystem);
            destroyer2.AddSystem(GameDataStore.GetShipSystem("Ga").Clone() as WeaponSystem);
            destroyer2.AddSystem(GameDataStore.GetShipSystem("Ia").Clone() as ShipSystem);
            destroyer2.AddSystem(GameDataStore.GetShipSystem("Qa").Clone() as ShipSystem);
            #endregion

            destroyer1.MapPosition = new MapIndex(1, 2, 2);
            destroyer1.Heading = 2;
            destroyer1.ImageName = @"White Counters\04 DD-1.gif";

            destroyer2.MapPosition = new MapIndex(1, 4, 3);
            destroyer2.Heading = 0;
            destroyer2.ImageName = @"Red Counters\04 DD-1.gif";
        }
        #endregion

        public IGUIFactory GuiFactory
        {
            get { return iGuiFactory; }
            protected set { iGuiFactory = value; }
        }

        public static MainForm TheForm()
        {
            return thisForm;
        }

        public static DockPanel MainDockPanel
        {
            get { return mainDockingPanel; }
        }

        internal ContextMenuStrip ViewTabContextMenu
        {
            get { return viewTabContextMenuStrip; }
        }

        /// <summary>
        /// Add active game and race names to the main title
        /// </summary>
        private void UpdateFormTitle()
        {
            string text = "Galactic Starfire";
            if (Game.ActiveGame != null)
            {
                text += " : " + Game.ActiveGame.Name;
                if (Race.ActiveRace != null)
                    text += " : " + Race.ActiveRace.Name;
            }
            Text = text;
        }

        ///
        /// Menu OnOpening Callbacks
        ///
        private void gameToolStripMenuItem_DropDownOpening(object sender, EventArgs e)
        {
            this.saveToolStripMenuItem.Enabled = Game.ActiveGame != null;
            this.gamePropertiesMenuItem.Enabled = Game.ActiveGame != null;
        }

        private void raceToolStripMenuItem_DropDownOpening(object sender, EventArgs e)
        {
            this.activeRaceToolStripMenuItem.Enabled = Game.ActiveGame != null && Race.Races.Count() > 0;
            this.newRaceToolStripMenuItem.Enabled = Game.ActiveGame != null;
            this.racePropertiesToolStripMenuItem.Enabled = Race.ActiveRace != null;
        }

        private void ordersStripMenuItem_DropDownOpening(object sender, EventArgs e)
        {
            this.buildUnitToolStripMenuItem.Enabled = Race.ActiveRace != null;
            this.buildIUToolStripMenuItem.Enabled = Race.ActiveRace != null;
            this.manageUnitsToolStripMenuItem.Enabled = Race.ActiveRace != null;
            this.managePopulationsToolStripMenuItem.Enabled = Race.ActiveRace != null;
            this.manageFleetsToolStripMenuItem.Enabled = Race.ActiveRace != null;
        }

        private void toolsStripMenuItem_DropDownOpening(object sender, EventArgs e)
        {
            this.unitDesignToolStripMenuItem.Enabled = Race.ActiveRace != null;
        }

        private void viewToolStripMenuItem_DropDownOpening(object sender, EventArgs e)
        {
            this.homeSystemToolStripMenuItem.Enabled = Race.ActiveRace != null;
            this.galaxyMapToolStripMenuItem.Enabled = Race.ActiveRace != null;
            this.economicDetailsToolStripMenuItem.Enabled = Race.ActiveRace != null;
            this.fleetsListToolStripMenuItem.Enabled = Race.ActiveRace != null;
            this.knownSystemsListToolStripMenuItem.Enabled = Race.ActiveRace != null;
            this.knownRacesListToolStripMenuItem.Enabled = Race.ActiveRace != null;
        }

        private void turnToolStripMenuItem_DropDownOpening(object sender, EventArgs e)
        {
            this.nextTurnToolStripMenuItem.Enabled = Game.ActiveGame != null && Game.ActiveGame.TurnComplete();
        }

        private void smToolsToolStripMenuItem_DropDownOpening(object sender, EventArgs e)
        {
            this.newStarSystemToolStripMenuItem.Enabled = Game.ActiveGame != null && Race.ActiveRace != null;
            this.raceRelationsToolStripMenuItem.Enabled = Game.ActiveGame != null && Race.Races.Count() > 1;
            this.unitDesignerToolStripMenuItem.Enabled = false;
        }

        ///
        /// Game menu callbacks
        ///
        private void newGameToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Commands.CreateNewGame();
            UpdateFormTitle();
        }

        private void saveToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Commands.SaveGame();
        }

        private void loadToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Commands.LoadGame();
            UpdateFormTitle();
        }

        private void propertiesMenuItem_Click(object sender, EventArgs e)
        {
            Commands.ShowGameProperties();
            UpdateFormTitle();
        }

        /// <summary>
        /// Exit the application
        /// </summary>
        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (Commands.QuitGame())
                Close();
        }

        ///
        /// Race menu callbacks
        ///
        private void activeRaceToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Commands.ShowActiveRaceDialog();
            UpdateFormTitle();
        }

        private void newRaceToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Commands.CreateRace();
            UpdateFormTitle();
        }

        private void racePropertiesToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Commands.ShowRaceProperties();
        }

        ///
        /// Orders callbacks
        ///
        private void buildUnitToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }

        private void buildIUToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }

        private void manageUnitsToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }

        private void managePopulationsToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }

        private void manageFleetsToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }

        ///
        /// Racial Tools callbacks
        ///
        private void unitDesignToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Commands.ShowUnitDesignerDialog();
        }

        ///
        /// View menu callbacks
        ///
        private void homeSystemToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Commands.OpenView(Race.ActiveRace.HomeSystem.MapId, ViewType.vtMAP_STRATEGIC);
        }

        private void galaxyMapToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }

        private void economicDetailsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Commands.OpenToolbox(GamePanelType.pECONOMY, DockState.DockLeft);
        }

        private void fleetsListToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Commands.OpenToolbox(GamePanelType.pFLEETLIST, DockState.DockRight);
        }

        private void knownSystemsListToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Commands.OpenToolbox(GamePanelType.pSYSTEMLIST, DockState.DockLeft);
        }

        private void knownRacesListToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Commands.OpenToolbox(GamePanelType.pKNOWNRACES, DockState.DockLeft);
        }

        ///
        /// Turn callbacks
        ///
        private void nextTurnToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Commands.NextTurn();
        }

        ///
        /// SM Tools callbacks
        ///
        private void newStarSystemToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Commands.CreateNewStarSystem();
        }

        private void raceRelationsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Commands.ShowRaceRelationsDialog();
        }

        private void unitDesignerToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Commands.ShowUnitDesignerDialog();
        }

        ///
        /// Tabs callbacks
        ///
        private void viewTabContextMenuStrip_Opening(object sender, CancelEventArgs e)
        {
            // Nothing for now.
        }

        private void viewTabMenuItemContextMenu_Click(object sender, EventArgs e)
        {
            ToolStripMenuItem menuItem = sender as ToolStripMenuItem;
            if (menuItem != null)
            {
                ContextMenuStrip contextMenu = menuItem.GetCurrentParent() as ContextMenuStrip;
                if (contextMenu != null)
                {
                    DockPane dockPane = contextMenu.SourceControl.Parent as DockPane;
                    if (dockPane != null)
                    {
                        IGameWindow gameWindow = dockPane.ActiveContent as IGameWindow;
                        if (gameWindow != null)
                        {
                            switch (menuItem.Tag.ToString())
                            {
                                case "Close":
                                    Commands.Close(gameWindow);
                                    break;
                                case "CloseAll":
                                    Commands.CloseAll();
                                    break;
                                case "CloseAllButThis":
                                    Commands.CloseAllButThis(gameWindow);
                                    break;
                                default:
                                    throw new NotImplementedException("Unknown menu item.");
                            }
                        }
                    }
                }
            }
        }
    }
}
